package ae.pcfc.etks.online.web.filter;

import java.io.IOException;
import java.util.Stack;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;

import ae.pcfc.etks.online.web.ConstantsAdmin;
import ae.pcfc.etks.online.web.model.BreadCrumbItem;

/**
 * Intercepts requests and places URL into breadcrumb stack.
 * 
 * @web.filter name="BreadCrumbFilter" *web.filter-mapping url-pattern="/*.do"
 * @web.filter-init-param name="maxStackSize" value="3"
 * 
 * 
 **/
public final class BreadCrumbFilter implements Filter {
	private int mMaxStackSize = 10;

	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;

		//HttpSession session = request.getSession(false);
		Stack<BreadCrumbItem> stack = null;
	       if (request.getSession(false) != null)
		          {
	           stack = (Stack<BreadCrumbItem>)request.getSession(false).getAttribute(ConstantsAdmin.BREADCRUMB);
	       }
	       if (stack == null)
		          {
	           stack = new Stack<BreadCrumbItem>();
	       }

		// This gives you a chance to look at your breadcrumb trail
		if (request.getQueryString() != null && request.getQueryString().equals("BreadCrumb")) {
			response.setContentType("text/html");
			ServletOutputStream out = response.getOutputStream();
			  for (int i=0; i<stack.size(); i++)
              {
				  out.println(stack.elementAt(i).toString() +"<br>");
              }
			out.flush();
			out.close();
			return;
		} else {
			chain.doFilter(req, resp);
		}

		StringBuffer url = request.getRequestURL();
		// now that we've successfully returned,
		// add url to stack if it isn't a Velocity page
		String servletPath = request.getServletPath();
		if (servletPath.indexOf("page") == -1 && servletPath.indexOf("comments") == -1 && request.getMethod().equalsIgnoreCase(RequestMethod.GET.name())) {
			if (request.getQueryString() != null) {
				url.append("?").append(request.getQueryString());
			}
			if (stack.size() == mMaxStackSize) {
				stack.remove(mMaxStackSize - 1);
			}
			String key = (String)request.getAttribute("titleKey");
			String menuItem = (String)request.getAttribute("menuItem");

			if(StringUtils.isNotBlank(key)){
				BreadCrumbItem bcItem = new BreadCrumbItem();
				bcItem.setTitleKey(key);
				bcItem.setUrlValue(url.toString());
				if(StringUtils.isNotBlank(menuItem)){
					bcItem.setMenuItem(menuItem);
				}
				if(stack.search(bcItem) == -1){
					if(StringUtils.isNotBlank(bcItem.getMenuItem())){
						stack.clear();
					}
					stack.push(bcItem);
				}else{
					do{
						if(stack.peek().equals(bcItem)){
							break;
						}else{
							stack.pop();
						}
					}while(!stack.isEmpty());
				}
			}
		}
		
		if (request.getSession(false) != null) {
			request.getSession(false).setAttribute(ConstantsAdmin.BREADCRUMB, stack);
		}
	}

	/**
	 * Initialize controller values of filter.
	 **/
	public void init(FilterConfig filterConfig) {
		// debug
		// System.out.println("BreadCrumbFilter is loaded");

		if (!StringUtils.isEmpty(filterConfig.getInitParameter("maxStackSize"))) {
			String temp = filterConfig.getInitParameter("maxStackSize");
			int mSS = Integer.parseInt(temp);
			if (mSS != 0) {
				mMaxStackSize = mSS;
			}
		}
	}

	/** destroy any instance values other than filterConfig **/
	public void destroy() {
		mMaxStackSize = 10;
	}
}